home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Lib / tkinter / FileDialog.py < prev    next >
Text File  |  1995-12-21  |  5KB  |  215 lines

  1. """File selection dialog classes.
  2.  
  3. Classes:
  4.  
  5. - FileDialog
  6. - LoadFileDialog
  7. - SaveFileDialog
  8.  
  9. XXX Bugs:
  10.  
  11. - The fields are not labeled
  12. - Default doesn't have absolute pathname
  13. - Each FileDialog instance can be used only once
  14. - There is no easy way for an application to add widgets of its own
  15.  
  16. """
  17.  
  18. from Tkinter import *
  19. from Dialog import Dialog
  20.  
  21. ANCHOR = 'anchor'
  22.  
  23. import os
  24. import fnmatch
  25.  
  26.  
  27. class FileDialog:
  28.  
  29.     """Standard file selection dialog -- no checks on selected file.
  30.  
  31.     Usage:
  32.  
  33.         d = FileDialog(master)
  34.         file = d.go(directory, pattern, default)
  35.         if file is None: ...canceled...
  36.  
  37.     """
  38.  
  39.     title = "File Selection Dialog"
  40.  
  41.     def __init__(self, master):
  42.     self.master = master
  43.     self.directory = None
  44.     self.top = Toplevel(master)
  45.     self.top.title(self.title)
  46.     self.filter = Entry(self.top)
  47.     self.filter.pack(fill=X)
  48.     self.filter.bind('<Return>', self.filter_command)
  49.     self.midframe = Frame(self.top)
  50.     self.midframe.pack(expand=YES, fill=BOTH)
  51.     self.dirs = Listbox(self.midframe)
  52.     self.dirs.pack(side=LEFT, expand=YES, fill=BOTH)
  53.     self.dirs.bind('<ButtonRelease-1>', self.dirs_select_event)
  54.     self.dirs.bind('<Double-ButtonRelease-1>', self.dirs_double_event)
  55.     self.files = Listbox(self.midframe)
  56.     self.files.pack(side=RIGHT, expand=YES, fill=BOTH)
  57.     self.files.bind('<ButtonRelease-1>', self.files_select_event)
  58.     self.files.bind('<Double-ButtonRelease-1>', self.files_double_event)
  59.     self.selection = Entry(self.top)
  60.     self.selection.pack(fill=X)
  61.     self.selection.bind('<Return>', self.ok_event)
  62.     self.botframe = Frame(self.top)
  63.     self.botframe.pack(fill=X)
  64.     self.ok_button = Button(self.botframe,
  65.                  text="OK",
  66.                  command=self.ok_command)
  67.     self.ok_button.pack(side=LEFT)
  68.     self.filter_button = Button(self.botframe,
  69.                     text="Filter",
  70.                     command=self.filter_command)
  71.     self.filter_button.pack(side=LEFT, expand=YES)
  72.     self.cancel_button = Button(self.botframe,
  73.                     text="Cancel",
  74.                     command=self.cancel_command)
  75.     self.cancel_button.pack(side=RIGHT)
  76.  
  77.     def go(self, directory=os.curdir, pattern="*", default=""):
  78.     self.directory = directory
  79.     self.set_filter(directory, pattern)
  80.     self.filter_command()
  81.     self.set_selection(default)
  82.     self.selection.focus_set()
  83.     self.top.grab_set()
  84.     try:
  85.         self.master.mainloop()
  86.     except SystemExit, how:
  87.         self.top.destroy()
  88.         return how
  89.  
  90.     def dirs_double_event(self, event):
  91. ##    self.dirs_select_event(event)
  92.     self.filter_command()
  93.  
  94.     def dirs_select_event(self, event):
  95.     dir, pat = self.get_filter()
  96.     subdir = self.dirs.get(ANCHOR)
  97.     dir = os.path.normpath(os.path.join(self.directory, subdir))
  98.     self.set_filter(dir, pat)
  99.  
  100.     def files_double_event(self, event):
  101. ##    self.files_select_event(event)
  102. ##    self.master.update_idletasks()
  103.     self.ok_command()
  104.  
  105.     def files_select_event(self, event):
  106.     file = self.files.get(ANCHOR)
  107.     self.set_selection(file)
  108.  
  109.     def ok_event(self, event):
  110.     self.ok_command()
  111.  
  112.     def ok_command(self):
  113.     raise SystemExit, self.selection.get()
  114.  
  115.     def filter_command(self, event=None):
  116.     dir, pat = self.get_filter()
  117.     try:
  118.         names = os.listdir(dir)
  119.     except os.error:
  120.         self.master.bell()
  121.         return
  122.     self.directory = dir
  123.     self.set_filter(dir, pat)
  124.     names.sort()
  125.     subdirs = [os.pardir]
  126.     matchingfiles = []
  127.     for name in names:
  128.         fullname = os.path.join(dir, name)
  129.         if os.path.isdir(fullname):
  130.         subdirs.append(name)
  131.         elif fnmatch.fnmatch(name, pat):
  132.         matchingfiles.append(name)
  133.     self.dirs.delete(0, END)
  134.     for name in subdirs:
  135.         self.dirs.insert(END, name)
  136.     self.files.delete(0, END)
  137.     for name in matchingfiles:
  138.         self.files.insert(END, name)
  139.     head, tail = os.path.split(self.selection.get())
  140.     if tail == os.curdir: tail = ''
  141.     self.set_selection(tail)
  142.  
  143.     def get_filter(self):
  144.     filter = self.filter.get()
  145.     if filter[-1:] == os.sep:
  146.         filter = filter + "*"
  147.     return os.path.split(filter)
  148.  
  149.     def cancel_command(self):
  150.     raise SystemExit, None
  151.  
  152.     def set_filter(self, dir, pat):
  153.     self.filter.delete(0, END)
  154.     self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*"))
  155.  
  156.     def set_selection(self, file):
  157.     self.selection.delete(0, END)
  158.     self.selection.insert(END, os.path.join(self.directory, file))
  159.  
  160.  
  161. class LoadFileDialog(FileDialog):
  162.  
  163.     """File selection dialog which checks that the file exists."""
  164.  
  165.     title = "Load File Selection Dialog"
  166.  
  167.     def ok_command(self):
  168.     file = self.selection.get()
  169.     if not os.path.isfile(file):
  170.         self.master.bell()
  171.     else:
  172.         raise SystemExit, file
  173.  
  174.  
  175. class SaveFileDialog(FileDialog):
  176.  
  177.     """File selection dialog which checks that the file may be created."""
  178.  
  179.     title = "Save File Selection Dialog"
  180.  
  181.     def ok_command(self):
  182.     file = self.selection.get()
  183.     if os.path.exists(file):
  184.         if os.path.isdir(file):
  185.         self.master.bell()
  186.         return
  187.         d = Dialog(self.master,
  188.                title="Overwrite Existing File Question",
  189.                text="Overwrite existing file %s?" % `file`,
  190.                bitmap='questhead',
  191.                default=0,
  192.                strings=("Yes", "Cancel"))
  193.         if d.num != 0: file = None
  194.     else:
  195.         head, tail = os.path.split(file)
  196.         if not os.path.isdir(head):
  197.         self.master.bell()
  198.         return
  199.     raise SystemExit, file
  200.  
  201.  
  202. def test():
  203.     """Simple test program."""
  204.     root = Tk()
  205.     root.withdraw()
  206.     fd = LoadFileDialog(root)
  207.     loadfile = fd.go()
  208.     fd = SaveFileDialog(root)
  209.     savefile = fd.go()
  210.     print loadfile, savefile
  211.  
  212.  
  213. if __name__ == '__main__':
  214.     test()
  215.